//
// Created by zeng on 2021/10/15.
//

#include "GetWeather.h"

//std::string GetWeather::key{"86815c8e4fc44d9484fc0721518ed7aa"};
httplib::Client GetWeather::cli{"https://devapi.qweather.com"};
httplib::Client GetWeather::cli_ID{"https://geoapi.qweather.com"};

GetWeather::GetWeather(std::string location) : location{location}, key{"86815c8e4fc44d9484fc0721518ed7aa"} {
    cli.set_follow_location(true);
    this->ID = get_ID();
}

std::string GetWeather::get_ID() {
    try {
        std::string path{"/v2/city/lookup?location=" + this->location + "&key=" + this->key + "&gzip=n"};
//        auto res = cli.Get(path.data());
//        httplib::Client cli_ID{"https://geoapi.qweather.com"};
        auto res = this->cli_ID.Get(path.data());
//        std::cout << res->status;
        if (res->status != 200) { throw res->status; }
        json ID_json = json::parse(res->body)["location"][0];
        std::string response = ID_json["id"];
        return response;
    }
    catch (int) {
//        JsonParsedString response{response_code};
//        response_code

        return get_ID();
    }

};

JsonParsedString GetWeather::get_weather_JsonParsedString() {
    try {
        std::string path{"/v7/weather/3d?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res = cli.Get(path.data());
        if (res->status != 200) { throw res->status; }
        json weather_json = json::parse(res->body)["daily"][1];
//        weather_json = weather_json["daily"][1];
        Weather weather{weather_json, res->status};
        JsonParsedString response{res->status, weather.GetValue()};
        return response;
    }
    catch (int response_code) {
        JsonParsedString response{response_code};
        return response;
    }
}

JsonParsedString GetWeather::get_tip_JsonParsedString() {
    try {
        std::string path{"/v7/indices/1d?type=0&location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res = cli.Get(path.data());
        if (res->status != 200) { throw res->status; }
        json tip_json = json::parse(res->body)["daily"];
//        std::cout << tip_json << std::endl;
//        for (int i = 0; i < tip_json["daily"].size(); ++i) {
//            std::cout << tip_json["daily"][i] << std::endl;
//        }
        Tip tip{tip_json, res->status};
        JsonParsedString response{res->status, tip.GetValue()};
        return response;
    }
    catch (int response_code) {
        JsonParsedString response{response_code};
        return response;
    }
}

JsonParsedString GetWeather::get_warn_JsonParsedString() {
    try {
        std::string path_now{"/v7/weather/now?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        std::string path_24h{"/v7/weather/24h?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res_now = cli.Get(path_now.data());
        auto res_24h = cli.Get(path_24h.data());
        if (res_24h->status != 200 && res_now->status != 200) { throw (res_24h->status); }
        std::string where_now = json::parse(res_now->body)["now"]["text"];
        std::string where_next = json::parse(res_24h->body)["hourly"][2]["text"];
        if ((where_now.find("雨") == std::string::npos) && (where_next.find("雨") != std::string::npos)) {
            JsonParsedString response{200, "小心3个小时内可能会下雨，请做好准备，照顾好自己"};
            return response;
        }
        else {
            JsonParsedString response{-1};
            return response;
        }
//        for (int i = 0; i < j1.size(); ++i) {
//            std::cout << j1[i]["text"] << std::endl;
//        }
//        std::cout << j1 << std::endl << j2 << std::endl;

//        std::cout << j1 << std::endl;
        return JsonParsedString{1};
    }
    catch (int response_code) {
        return JsonParsedString{response_code};
    }
}

Weather GetWeather::get_weather() {
    try {
        std::string path{"/v7/weather/3d?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res = cli.Get(path.data());
        if (res->status != 200) { throw res->status; }
        json weather_json = json::parse(res->body)["daily"][1];
//        weather_json = weather_json["daily"][1];
        Weather weather{weather_json, res->status};
        return weather;
    }
    catch (int response_code) {
        Weather weather{response_code};
        return weather;
    }
}

Tip GetWeather::get_tip() {
    try {
        std::string path{"/v7/indices/1d?type=0&location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res = cli.Get(path.data());
        if (res->status != 200) { throw res->status; }
        json tip_json = json::parse(res->body)["daily"];
//        std::cout << tip_json << std::endl;
//        for (int i = 0; i < tip_json["daily"].size(); ++i) {
//            std::cout << tip_json["daily"][i] << std::endl;
//        }
        Tip tip{tip_json, res->status};
        return tip;
    }
    catch (int response_code) {
        Tip tip{response_code};
        return tip;
    }
}

Warn GetWeather::get_warn() {
    try {
        std::string path_now{"/v7/weather/now?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        std::string path_24h{"/v7/weather/24h?location=" + this->ID + "&key=" + this->key + "&gzip=n"};
        auto res_now = cli.Get(path_now.data());
        auto res_24h = cli.Get(path_24h.data());
        if (res_24h->status != 200 && res_now->status != 200) { throw (res_24h->status); }
        std::string where_now = json::parse(res_now->body)["now"]["text"];
        std::string where_next = json::parse(res_24h->body)["hourly"][2]["text"];
        if ((where_now.find("雨") == std::string::npos) && (where_next.find("雨") != std::string::npos)) {
            Warn warn{200};
            return warn;
        }
        else {
            Warn warn{-1};
            return warn;
        }
//        for (int i = 0; i < j1.size(); ++i) {
//            std::cout << j1[i]["text"] << std::endl;
//        }
//        std::cout << j1 << std::endl << j2 << std::endl;

//        std::cout << j1 << std::endl;
        return Warn{1};
    }
    catch (int response_code) {
        return Warn{response_code};
    }
}
